/**
 * @Copyright ®2015 Sinosoft Co. Ltd. All rights reserved.<br/>
 * 项目名称 : 中科软支付平台
 * 创建日期 : 2016年12月22日
 * 修改历史 : 
 *     1. [2016年12月22日]创建文件 by liuyujia
 */
package com.sinosoft.sinopay.web.agentpay.biz.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sinosoft.sinocloud.platform.base.SinoBaseService;
import com.sinosoft.sinocloud.platform.common.exception.biz.IllegalRequestException;
import com.sinosoft.sinocloud.platform.common.util.DateUtil;
import com.sinosoft.sinocloud.platform.common.util.MathUtil;
import com.sinosoft.sinocloud.platform.common.util.PersonIDUtil;
import com.sinosoft.sinopay.api.common.config.ENUM_PAY_TYPE;
import com.sinosoft.sinopay.api.common.dto.pay.PayAccountInfoDTO;
import com.sinosoft.sinopay.api.common.dto.pay.PaymentInfoDetailDTO;
import com.sinosoft.sinopay.customer.dto.CustomerInfoDTO;
import com.sinosoft.sinopay.customer.facade.CustomerFacadeService;
import com.sinosoft.sinopay.customer.facade.CustomerQueryFacadeService;
import com.sinosoft.sinopay.merchants.dto.MerchantSignInfo;
import com.sinosoft.sinopay.merchants.facade.MerchantInfoFacadeService;
import com.sinosoft.sinopay.paytrade.config.ENUM_PAY_STATUS;
import com.sinosoft.sinopay.paytrade.dto.PaymentRequestDTO;
import com.sinosoft.sinopay.paytrade.dto.PaymentTradeReqDTO;
import com.sinosoft.sinopay.paytrade.facade.PaymentTradeFacadeService;
import com.sinosoft.sinopay.paytrade.facade.PaymentTradeQueryFacadeService;
import com.sinosoft.sinopay.web.agentpay.biz.config.AgentPaymentConstants;
import com.sinosoft.sinopay.web.agentpay.biz.config.ENUM_REPORT_NOTIFYTYPE;
import com.sinosoft.sinopay.web.agentpay.biz.service.PaymentAgentService;
import com.sinosoft.sinopay.web.agentpay.dto.AgentEntryRequsetDTO;
import com.sinosoft.sinopay.web.util.AgentSignUtil;

/**  
 * 【类或接口功能描述】
 * @author liuyujia
 * @date 2016年12月22日 下午3:30:57 
 * @version V1.0  
 */
@Service
public class PaymentAgentServiceImpl extends SinoBaseService implements PaymentAgentService {

	@Autowired
	private PaymentTradeFacadeService paymentTradeFacadeService;
	@Autowired
	private CustomerFacadeService customerFacadeService;
	@Autowired
	private CustomerQueryFacadeService customerQueryFacadeService;
	@Autowired
	private MerchantInfoFacadeService merchantSecurityFacadeService;
	@Autowired
	private PaymentTradeQueryFacadeService paymentTradeQueryFacadeService;
	/** 商户签名信息缓存map */
	private Map<String, String> signKeysMap;
	
	@Override
	public String dealWechatPayRequest(AgentEntryRequsetDTO tAgentEntryRequsetDTO) {
		//持久化客户信息
		CustomerInfoDTO tCustomerInfo = new CustomerInfoDTO();
		tCustomerInfo.setBirthday(tAgentEntryRequsetDTO.getAccountBirthday());
		tCustomerInfo.setCustomerName(tAgentEntryRequsetDTO.getAccountName());
		tCustomerInfo.setGender(tAgentEntryRequsetDTO.getAccountGender());
		tCustomerInfo.setMechantCode(tAgentEntryRequsetDTO.getMerchantCode());
		tCustomerInfo.setIdNo(tAgentEntryRequsetDTO.getIdNo());
		tCustomerInfo.setIdType(tAgentEntryRequsetDTO.getIdType());
		//持久化交易信息
		PaymentRequestDTO tPaymentRequest = new PaymentRequestDTO();
		tPaymentRequest.setMerchantCode(tAgentEntryRequsetDTO.getMerchantCode());
		tPaymentRequest.setBizNo(tAgentEntryRequsetDTO.getBizNo());
		tPaymentRequest.setBizType(tAgentEntryRequsetDTO.getBizType());
		tPaymentRequest.setSerialNo(tAgentEntryRequsetDTO.getSerialNo());
		tPaymentRequest.setPayAmount(tAgentEntryRequsetDTO.getPayAmount());
		//持久化账户信息
		PayAccountInfoDTO tPayAccountInfo = new PayAccountInfoDTO();
		tPayAccountInfo.setAccountName(tAgentEntryRequsetDTO.getAccountName());
		tPayAccountInfo.setCardType(tAgentEntryRequsetDTO.getIdType());
		tPayAccountInfo.setCardNo(tAgentEntryRequsetDTO.getIdNo());
		tPaymentRequest.setPayAccount(tPayAccountInfo);
		//调用客户服务  老客户返回1, 新客户返回0
		Integer customer = customerFacadeService.saveCustomerPayAccountInfo(tPayAccountInfo);
		System.out.println("客户增改标记："+customer);
		//调用交易服务
		String tPayNo = paymentTradeFacadeService.newPayTrade(tPaymentRequest);
		//生成合法支付链接地址
		Long timestap = new Date().getTime();
		tAgentEntryRequsetDTO.setRemark(tPayNo);
		//签名算法
		String signMsg = getMerchantSignValid(tAgentEntryRequsetDTO.getMerchantCode(), tAgentEntryRequsetDTO);
		StringBuffer tPayUrl = new StringBuffer(AgentPaymentConstants.PAY_REQUEST_URL);
		tPayUrl.append("payNo=");
		tPayUrl.append(tPayNo);
		tPayUrl.append("&orderNo=");
		tPayUrl.append(tAgentEntryRequsetDTO.getBizNo());
		tPayUrl.append("&signMsg=");
		tPayUrl.append(signMsg);
		tPayUrl.append("&t=");
		tPayUrl.append(timestap);
		//3.返回支付URL
		return tPayUrl.toString();
	}

	private String getMerchantSignValid(String merchantCode, AgentEntryRequsetDTO tAgentEntryRequsetDTO) {
		if(signKeysMap==null || signKeysMap.size()==0){
			 //获取全部的商户签名信息
			 signKeysMap = merchantSecurityFacadeService.getAllMerchantSignKeys();
		 }
		//获取商户对应的key值
		if(signKeysMap.get(merchantCode)==null){
			throw new IllegalRequestException("商户不存在");
		}
		String tSignKey = signKeysMap.get(merchantCode);
		//封装签名参数
		Map<String,String> tSignInfoMap = new HashMap<String,String>();
		tSignInfoMap.put("merchantCode",merchantCode);
       tSignInfoMap.put("bizNo", tAgentEntryRequsetDTO.getBizNo());
       tSignInfoMap.put("bizType", tAgentEntryRequsetDTO.getBizType());
       tSignInfoMap.put("transType", tAgentEntryRequsetDTO.getTransType());
       tSignInfoMap.put("productName", tAgentEntryRequsetDTO.getTransDesc());
       tSignInfoMap.put("serialNo", tAgentEntryRequsetDTO.getSerialNo());
       tSignInfoMap.put("accountName", tAgentEntryRequsetDTO.getAccountName());
       tSignInfoMap.put("accountGender", tAgentEntryRequsetDTO.getAccountGender());
       Date tAccountBirthday = tAgentEntryRequsetDTO.getAccountBirthday();
       String birthday = DateUtil.getDateStr(tAccountBirthday, "yyyy-MM-dd");
       tSignInfoMap.put("accountBirthday", birthday);
       tSignInfoMap.put("idType", tAgentEntryRequsetDTO.getIdType());
       tSignInfoMap.put("idNo", tAgentEntryRequsetDTO.getIdNo());
       String tPayAmount = transAmount(tAgentEntryRequsetDTO.getPayAmount());
       tSignInfoMap.put("payAmount",tPayAmount);//金额转换成分
       Date tRequestDate = tAgentEntryRequsetDTO.getRequestDate();
       String date = DateUtil.getDateStr(tRequestDate, "yyyy-MM-dd");
       tSignInfoMap.put("requestDate",date);
       tSignInfoMap.put("remark", tAgentEntryRequsetDTO.getRemark());
       String tCompareSignMsg = AgentSignUtil.encryMD5(tSignInfoMap,tSignKey);
		return tCompareSignMsg;
	}
	
	/**
	 * 金额元转分
	 * @param tPayAmount
	 * @return
	 */
	private String transAmount(BigDecimal tPayAmount){
			 //格式化金额
			 String gPayAmount = MathUtil.formatAmount(tPayAmount);
	         BigDecimal payAmount = new BigDecimal(gPayAmount);
	         BigDecimal fen = payAmount.multiply(new BigDecimal("100"));
	         long fenAmount = fen.intValue();
	         String money = String.valueOf(fenAmount);
		return money;
		
	}

	@Override
	public PaymentInfoDetailDTO getPaymentTradeForPayNo(String payNo) {
		return paymentTradeQueryFacadeService.queryPaymentOrderByPayNo(payNo);
	}

	@Override
	public String getCustomerNo(PaymentInfoDetailDTO tPaymentInfoDetailDTO) {
		CustomerInfoDTO tCustomerInfoDTO = new CustomerInfoDTO();
		tCustomerInfoDTO.setCustomerName(tPaymentInfoDetailDTO.getAccountName());
		String Birthday = PersonIDUtil.getBirthByIdCard(tPaymentInfoDetailDTO.getIdNo());
		String gender = PersonIDUtil.getGenderByIdCard(tPaymentInfoDetailDTO.getIdNo());
		tCustomerInfoDTO.setGender(gender);
		tCustomerInfoDTO.setIdNo(tPaymentInfoDetailDTO.getIdNo());
		tCustomerInfoDTO.setIdType(tPaymentInfoDetailDTO.getIdType());
		tCustomerInfoDTO.setBirthday(DateUtil.parseDate(Birthday,"yyyyMMdd"));
		return customerQueryFacadeService.queryCustomerNo(tCustomerInfoDTO);
	}

	@Override
	public String getNotifyUrlByMerchant(String merchantCode, String notifyWay)	throws Exception {
		String notifyUrl = null;
		MerchantSignInfo tMerchantSignInfo = merchantSecurityFacadeService.getMerchantByCode(merchantCode);
		if(notifyWay==ENUM_REPORT_NOTIFYTYPE.PAGE_NOTIFY.code()){
			notifyUrl = tMerchantSignInfo.getPayPageNotifyURL();
		}
		else
			notifyUrl = tMerchantSignInfo.getPayBackNotifyURL();
		return notifyUrl;
	}

	@Override
	public void addPaymentInfo(String payNo) throws Exception {
		PaymentInfoDetailDTO tPaymentInfoDetailDTO = getPaymentTradeForPayNo(payNo);
		PaymentTradeReqDTO cPaymentTradeReqDTO = new PaymentTradeReqDTO();
		cPaymentTradeReqDTO.setSerialNo(tPaymentInfoDetailDTO.getSerialNo());
		cPaymentTradeReqDTO.setBizNo(tPaymentInfoDetailDTO.getBizNo());
		cPaymentTradeReqDTO.setPayNo(payNo);
		cPaymentTradeReqDTO.setMerchantCode(tPaymentInfoDetailDTO.getMerchantCode());
		cPaymentTradeReqDTO.setThirdpayCode(tPaymentInfoDetailDTO.getThirdpayCode());
		cPaymentTradeReqDTO.setBizType(tPaymentInfoDetailDTO.getBizType());
		cPaymentTradeReqDTO.setPayWay("");
		cPaymentTradeReqDTO.setPayType(ENUM_PAY_TYPE.AGENT.code());
		cPaymentTradeReqDTO.setPayStatus(ENUM_PAY_STATUS.PAY_WAIT.code());
		cPaymentTradeReqDTO.setPayAmount(tPaymentInfoDetailDTO.getPayAmount());
		cPaymentTradeReqDTO.setPayDate(tPaymentInfoDetailDTO.getPayDate());
		cPaymentTradeReqDTO.setTradeDesc(tPaymentInfoDetailDTO.getTradeDesc());
		cPaymentTradeReqDTO.setPayAccountName(tPaymentInfoDetailDTO.getAccountName());
		cPaymentTradeReqDTO.setPayIdType(tPaymentInfoDetailDTO.getIdType());
		cPaymentTradeReqDTO.setPayIdNo(tPaymentInfoDetailDTO.getIdNo());
		cPaymentTradeReqDTO.setPayAccountMobile(tPaymentInfoDetailDTO.getMobile());
		cPaymentTradeReqDTO.setCurrency("CNY");
		cPaymentTradeReqDTO.setCreateDate(new Date());
		paymentTradeFacadeService.addPaymentInfo(cPaymentTradeReqDTO);
	}
}
